package com.tisumoon.msg.data;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

import com.tisumoon.Notifications;
import com.tisumoon.data.MailBean;
import com.tisumoon.data.MsgBean;
import com.tisumoon.data.api.SearchLocal.Person;
import com.tisumoon.helper.DayNoonHelper;
import com.tisumoon.msg.data.abs.SendEntity;
import com.tisumoon.msg.data.bean.RelationshipBean;
import com.tisumoon.msg.data.bean.SayHiBean;
import com.tisumoon.msg.data.bean.receive.ArriveState;
import com.tisumoon.msg.data.bean.receive.ArriveStateUnload;
import com.tisumoon.msg.data.bean.receive.ArriveStateUnload.Info;
import com.tisumoon.msg.data.bean.receive.Mail;
import com.tisumoon.msg.data.bean.receive.MsgReceived;
import com.tisumoon.msg.data.bean.receive.SayHi;
import com.tisumoon.msg.data.bean.receive.Ya;
import com.tisumoon.msg.data.bean.receive.Yo;
import com.tisumoon.msg.data.bean.send.MsgSend;
import com.tisumoon.msg.data.bean.send.StateBack;
import com.wei.c.data.abs.IJson;
import com.wei.c.utils.ArrayUtils;
import com.wei.c.utils.SPref;

public class ContentHelper {
	public static final String TAG				= ContentHelper.class.getSimpleName();
	public static final int TIME_INTERVAL		= 5*60*1000;
	public static char DOT						= '`';

	public static long getTimeOutOfDatePoint() {
		return System.currentTimeMillis() - TIME_INTERVAL;
	}

	/**服务端时间是精确到秒的**/
	public static long convertServerTimeToLocal(long time) {
		return time * 1000;
	}

	public static long getMaxOrderNumSendOrReceived(ContentResolver contentResolver, long id_me, long id_u) {
		return Math.max(MSG_RECEIVED.getMaxOrderNum(contentResolver, id_me, id_u),
				MSG_SEND.getMaxOrderNum(contentResolver, id_me, id_u));
	}

	public static long getMaxTimeSendOrReceived(ContentResolver contentResolver, long id_me, long id_u) {
		long[] orderNumAndReceiveTime = MSG_RECEIVED.getMaxOrderNumAndSendTime(contentResolver, id_me, id_u);
		long[] orderNumAndSendTime = MSG_SEND.getMaxOrderNumAndSendTime(contentResolver, id_me, id_u);
		//由于这个时间是以本地为准，那么就选最大的吧
		return Math.max(orderNumAndReceiveTime[1], orderNumAndSendTime[1]);
	}

	public static final class SAY_HI {

		public static void sendSayHi(ContentResolver contentResolver, long id_me, long id_u) {
			SEND_ENTITY.insertNewEntity(contentResolver, id_me, id_u, new com.tisumoon.msg.data.bean.send.SayHi(id_u), true, 0, 0);
		}

		public static long receive(ContentResolver contentResolver, long id_me, SayHi sayhi) {
			ContentValues values = new  ContentValues();
			values.put(MSG.DbColumns.SayHi._ID_ME, id_me);
			values.put(MSG.DbColumns.SayHi._ID_U, sayhi.fromuid);
			values.put(MSG.DbColumns.SayHi._U_NAME, sayhi.uname);
			values.put(MSG.DbColumns.SayHi._FACE_PATH, sayhi.facepath);
			values.put(MSG.DbColumns.SayHi._TIME_SEND, sayhi.time);
			return ContentUris.parseId(contentResolver.insert(MSG.URI_SAY_HI, values));
		}

		public static void updateRead(ContentResolver contentResolver, long id) {
			update(contentResolver, id, 1);
		}

		public static void updateFeedBack(ContentResolver contentResolver, long id) {
			update(contentResolver, id, 2);
		}

		public static void update(ContentResolver contentResolver, long id, int fb_state) {
			ContentValues values = new  ContentValues();
			values.put(MSG.DbColumns.SayHi._FB_STATE, fb_state);
			contentResolver.update(ContentUris.withAppendedId(MSG.URI_SAY_HI, id), values, null, null);
		}

		public static int getCount(ContentResolver contentResolver, long id_me) {
			Cursor cursor = contentResolver.query(MSG.URI_SAY_HI, new String[]{"count(*)"}, MSG.DbColumns.SayHi._ID_ME + "=? AND " + MSG.DbColumns.SayHi._FB_STATE + "=?",
					new String[]{String.valueOf(id_me), 0 + ""}, null);
			int count = 0;
			if (cursor != null) {
				if (cursor.moveToNext()) {
					count = cursor.getInt(0);
				}
				cursor.close();
			}
			return count;
		}

		public static List<SayHiBean> getSayHis(ContentResolver contentResolver, long id_me) {
			Cursor cursor = contentResolver.query(MSG.URI_SAY_HI, null, MSG.DbColumns.SayHi._ID_ME + "=? AND " + MSG.DbColumns.SayHi._FB_STATE + "=?",
					new String[]{String.valueOf(id_me), 0 + ""}, null);
			List<SayHiBean> list = new ArrayList<SayHiBean>();
			if (cursor != null) {
				while (cursor.moveToNext()) {
					SayHiBean sayHi = new SayHiBean();
					sayHi._id = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.SayHi._ID));
					sayHi.fromuid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.SayHi._ID_U));
					sayHi.time = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.SayHi._TIME_SEND));
					sayHi.uname = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.SayHi._U_NAME));
					sayHi.facepath = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.SayHi._FACE_PATH));
					sayHi.fbState = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.SayHi._FB_STATE));
					list.add(sayHi);
				}
				cursor.close();
			}
			return list;			
		}
	}

	public static final class YO {
		//TODO 关于好友关系的筛选暂不做
		public static void sendYo(ContentResolver contentResolver, long id_me, long id_u) {
			SEND_ENTITY.insertNewEntity(contentResolver, id_me, id_u, new com.tisumoon.msg.data.bean.send.Yo(id_u), true, 0, 0);
		}

		public static void receive(Context context, long id_me, Yo yo) {
			//查询好友昵称，并显示通知
			RelationshipBean bean = RELATIONSHIP.getRelationship(context.getContentResolver(), id_me, yo.fromuid);
			//同时实现了，如果好友列表里面没有的话就不显示
			if (bean != null) {
				Notifications.showNotification(context, Notifications.TYPE_YO, bean.name + " Yo了你一下", 
						DayNoonHelper.getDayNoonForNotification(context));
			}
		}
	}

	public static final class YA_AND_MAIL {
		public static void sendYa(ContentResolver contentResolver, long id_me, long id_u) {
			SEND_ENTITY.insertNewEntity(contentResolver, id_me, id_u, new com.tisumoon.msg.data.bean.send.Ya(id_u), true, 0, 0);
		}

		public static synchronized long receiveYa(Context context, long id_me, Ya ya) {
			if (!isBlock(context)) {
				Notifications.showNotification(context, Notifications.TYPE_YO, ya.name + " Ya了你一下",
						DayNoonHelper.getDayNoonForNotification(context));
				/*不需要广播，通过监听uri来实现更新
			Intent i = new Intent(Const.Broadcast.YA_RECEIVE);
			i.putExtra(Const.Extra.sKey_ya_json, yo.toJson());
			context.sendBroadcast(i);*/
			}
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.YaAndMail._ID_ME, id_me);
			values.put(MSG.DbColumns.YaAndMail._ID_U, ya.fromuid);
			values.put(MSG.DbColumns.YaAndMail._NAME, ya.name);
			values.put(MSG.DbColumns.YaAndMail._ICON, ya.head);
			values.put(MSG.DbColumns.YaAndMail._GENDER, ya.sex);
			values.put(MSG.DbColumns.YaAndMail._DISTANCE, ya.distance);
			values.put(MSG.DbColumns.YaAndMail._TIME_SEND, ya.time);
			values.put(MSG.DbColumns.YaAndMail._TYPE, 0);
			values.put(MSG.DbColumns.YaAndMail._CONTENT, "");
			return ContentUris.parseId(context.getContentResolver().insert(MSG.URI_YA_AND_MAIL, values));
		}

		public static void sendMail(ContentResolver contentResolver, long id_me, long id_u, String content) {
			SEND_ENTITY.insertNewEntity(contentResolver, id_me, id_u, new com.tisumoon.msg.data.bean.send.Mail(id_u, content), true, 0, 0);
		}

		public static long receiveMail(Context context, long id_me, Mail mail) {
			if (!isBlock(context)) {
				Notifications.showNotification(context, Notifications.TYPE_MAIL, mail.name + " 给你发了一封私信", "点击查看私信");
			}
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.YaAndMail._ID_ME, id_me);
			values.put(MSG.DbColumns.YaAndMail._ID_U, mail.fromuid);
			values.put(MSG.DbColumns.YaAndMail._NAME, mail.name);
			values.put(MSG.DbColumns.YaAndMail._ICON, mail.head);
			values.put(MSG.DbColumns.YaAndMail._GENDER, mail.sex);
			values.put(MSG.DbColumns.YaAndMail._DISTANCE, mail.distance);
			values.put(MSG.DbColumns.YaAndMail._TIME_SEND, mail.time);
			values.put(MSG.DbColumns.YaAndMail._TYPE, 1);
			values.put(MSG.DbColumns.YaAndMail._CONTENT, mail.contents);
			return ContentUris.parseId(context.getContentResolver().insert(MSG.URI_YA_AND_MAIL, values));
		}

		public static List<Person> getYaOrMailList(ContentResolver contentResolver, long id_me) {
			Cursor cursor = contentResolver.query(MSG.URI_YA_AND_MAIL, null, MSG.DbColumns.YaAndMail._ID_ME + "=" + id_me,
					null, MSG.DbColumns.YaAndMail._TIME_SEND + " DESC");
			Map<Long, Person> map = new LinkedHashMap<Long, Person>();
			if (cursor != null) {
				Person person;
				while (cursor.moveToNext()) {
					long uid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._ID_U));
					person = map.get(uid);
					if (person == null) {
						person = new Person();
						person.uid = uid;
						person.info = new Person.Info();
						person.info.uid = person.uid;
						person.info.name = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._NAME));
						person.info.head = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._ICON));
						person.info.sex = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._GENDER));
						person.distance = cursor.getFloat(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._DISTANCE));
						person.times = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._TIME_SEND));
						map.put(person.uid, person);
					}
					if (cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._TYPE)) == 1) {
						person.mailCount++;
					} else {
						person.yaCount++;
					}
				}
				cursor.close();
			}
			List<Person> list = new ArrayList<Person>();
			list.addAll(map.values());
			return list;
		}

		public static MailBean getMail(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_YA_AND_MAIL, null,
					MSG.DbColumns.YaAndMail._ID_ME + "=? AND " + MSG.DbColumns.YaAndMail._ID_U + "=? AND " + MSG.DbColumns.YaAndMail._TYPE + "=1",
					new String[]{String.valueOf(id_me), String.valueOf(id_u)}, MSG.DbColumns.YaAndMail._TIME_SEND + " ASC");
			MailBean mail = null;
			if (cursor != null) {
				if (cursor.moveToNext()) {
					long id = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._ID));
					mail = new MailBean(id);
					mail.fromuid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._ID_U));
					mail.name = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._NAME));
					mail.head = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._ICON));
					mail.sex = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._GENDER));
					mail.distance = cursor.getFloat(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._DISTANCE));
					mail.time = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._TIME_SEND));
					mail.contents = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._CONTENT));
				}
				cursor.close();
			}
			return mail;
		}

		public static synchronized void deleteMailOrYaAndKeepOne(ContentResolver contentResolver, long id_mail_db) {
			int count = getCount(contentResolver, id_mail_db);
			if (count > 1) {
				//删除所有的ya
				long[] ids = getIds(contentResolver, id_mail_db);
				if (ids != null) contentResolver.delete(MSG.URI_YA_AND_MAIL, 
						MSG.DbColumns.YaAndMail._ID_ME + "=? AND " + MSG.DbColumns.YaAndMail._ID_U + "=? AND " +
								MSG.DbColumns.YaAndMail._TYPE + "=?",
								new String[]{String.valueOf(ids[0]), String.valueOf(ids[1]), String.valueOf(0)});
			}
			//先更新为非mail标记
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.YaAndMail._TYPE, 0);
			contentResolver.update(ContentUris.withAppendedId(MSG.URI_YA_AND_MAIL, id_mail_db), values, null, null);
		}

		public static long[] getIds(ContentResolver contentResolver, long id_mail_db) {
			Cursor cursor = contentResolver.query(ContentUris.withAppendedId(MSG.URI_YA_AND_MAIL, id_mail_db), null, null, null, null);
			long[] ids = null;
			if (cursor != null) {
				if (cursor.moveToNext()) {
					ids = new long[2];
					ids[0] = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._ID_ME));
					ids[1] = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.YaAndMail._ID_U));
				}
				cursor.close();
			}
			return ids;
		}

		public static int getCount(ContentResolver contentResolver, long id_mail_db) {
			int count = 0;
			long[] ids = getIds(contentResolver, id_mail_db);
			if (ids != null) count = getCount(contentResolver, ids[0], ids[1]);
			return count;
		}

		public static int getCount(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_YA_AND_MAIL, new String[]{"COUNT(*)"},
					MSG.DbColumns.YaAndMail._ID_ME + "=? AND " + MSG.DbColumns.YaAndMail._ID_U + "=?",
					new String[]{String.valueOf(id_me), String.valueOf(id_u)}, null);
			int count = 0;
			if (cursor != null) {
				if (cursor.moveToNext()) count = cursor.getInt(0);
				cursor.close();
			}
			return count;
		}

		public static boolean isBlock(Context context) {
			return SPref.getBooleanFromFile(context, YA_AND_MAIL.class, "ya.block");
		}

		public static void setBlock(Context context, boolean block) {
			SPref.saveBooleanAsFile(context, YA_AND_MAIL.class, "ya.block", block);
		}
	}

	public static final class SEND_ENTITY {

		public static long insertNewEntity(ContentResolver contentResolver, long id_me, long id_u, IJson<?> jsonable, boolean state_back, long time_local, int priority) {
			ContentValues values = new  ContentValues();
			values.put(MSG.DbColumns.SendEntity._ID_ME, id_me);
			values.put(MSG.DbColumns.SendEntity._ID_U, id_u);
			values.put(MSG.DbColumns.SendEntity._JSON, jsonable.toJson());
			values.put(MSG.DbColumns.SendEntity._STATE_BACK, state_back);
			values.put(MSG.DbColumns.SendEntity._TIME, time_local);
			values.put(MSG.DbColumns.SendEntity._PRIORITY, priority);
			return ContentUris.parseId(contentResolver.insert(MSG.URI_SEND_ENTITY, values));
		}

		public static Cursor getCursor(ContentResolver contentResolver, long id_me) {
			return contentResolver.query(MSG.URI_SEND_ENTITY, null, MSG.DbColumns.SendEntity._ID_ME + "=" + id_me,
					null, MSG.DbColumns.SendEntity._PRIORITY);
		}

		public static SendEntity<String> getSendEntity(ContentResolver contentResolver, Cursor cursor) {
			while (cursor.moveToNext()) {
				long _id = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.SendEntity._ID));
				boolean _stateBack = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.SendEntity._STATE_BACK)) != 0;
				if (!_stateBack) {	//sayhi或反馈状态，不管有没有过期，都要发出去
					long _time = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.SendEntity._TIME));
					if (_time < getTimeOutOfDatePoint()) {	//超过5分钟，则变更为不发送
						ARRIVE_STATE.updateNotSendWithSendEntityId(contentResolver, _id);
						delete(contentResolver, _id);
						continue;
					}
				}
				String _json = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.SendEntity._JSON));
				return new SendEntity<String>(_id, _json, _stateBack);
			}
			return null;
		}

		public static void updateEntitySended(ContentResolver contentResolver, SendEntity<?> sendEntity) {
			if (!sendEntity.stateBack) ARRIVE_STATE.updateSendedWithSendEntityId(contentResolver, sendEntity.id);
			delete(contentResolver, sendEntity.id);
		}

		public static void delete(ContentResolver contentResolver, long id) {
			contentResolver.delete(ContentUris.withAppendedId(MSG.URI_SEND_ENTITY, id), null, null);
		}
	}

	public static final class MSG_SEND {

		public static synchronized long insertNewMsg(ContentResolver contentResolver, long id_me, MsgSend msgSend) {
			ContentValues values = new  ContentValues();
			values.put(MSG.DbColumns.MsgSend._ID_ME, id_me);
			values.put(MSG.DbColumns.MsgSend._ID_U, msgSend.sendtoid);
			values.put(MSG.DbColumns.MsgSend._TYPE_SENDER, msgSend._type_sender);
			values.put(MSG.DbColumns.MsgSend._TYPE_CONTENT, msgSend.ctype);
			values.put(MSG.DbColumns.MsgSend._CONTENT, msgSend.cvalue);
			values.put(MSG.DbColumns.MsgSend._NO, msgSend.no);
			values.put(MSG.DbColumns.MsgSend._TIME_LOCAL, msgSend._time_local);
			long id;
			synchronized (ContentHelper.class) {
				msgSend._order_num = getMaxOrderNumSendOrReceived(contentResolver, id_me, msgSend.sendtoid) + 1;
				values.put(MSG.DbColumns.MsgSend._ORDER_NUM, msgSend._order_num);
				id = ContentUris.parseId(contentResolver.insert(MSG.URI_MSG_SEND, values));
			}
			long sendEntityId = SEND_ENTITY.insertNewEntity(contentResolver, id_me, msgSend.sendtoid, msgSend, false, msgSend._time_local, 0);
			values.clear();
			values.put(MSG.DbColumns.MsgSend._ID_SEND_ENTITY, sendEntityId);
			contentResolver.update(ContentUris.withAppendedId(MSG.URI_MSG_SEND_ENTITY_ID, id), values, null, null);
			return id;
		}

		public static synchronized void delete(ContentResolver contentResolver, long id_me, long id_u) {
			contentResolver.delete(MSG.URI_MSG_SEND, MSG.DbColumns.MsgSend._ID_ME + "=? AND " +
					MSG.DbColumns.MsgSend._ID_U + "=?", new String[]{String.valueOf(id_me), String.valueOf(id_u)});
		}

		public static void resendMsg(ContentResolver contentResolver, long msgId) {
			Cursor cursor = contentResolver.query(ContentUris.withAppendedId(MSG.URI_MSG_SEND, msgId), null, null, null, null);
			MsgSend msgSend = null;
			if (cursor != null) {
				if (cursor.moveToNext()) {
					long myid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ID_ME));
					long sendtoid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ID_U));
					int type = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgSend._TYPE_CONTENT));
					String content = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.MsgSend._CONTENT));
					long timelocal = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._TIME_LOCAL));
					long no = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._NO));
					msgSend = new MsgSend(myid, sendtoid, type, content, timelocal, no);
				}
			}
			long sendEntityId = SEND_ENTITY.insertNewEntity(contentResolver, msgSend._id_me, msgSend.sendtoid, msgSend, false, System.currentTimeMillis(), 0);
			ContentValues values = new  ContentValues();
			values.put(MSG.DbColumns.MsgSend._ID_SEND_ENTITY, sendEntityId);
			contentResolver.update(ContentUris.withAppendedId(MSG.URI_MSG_SEND_ENTITY_ID, msgId), values, null, null);
		}

		public static long getMaxOrderNum(ContentResolver contentResolver, long id_me, long id_u) {
			return getMaxOrderNumAndSendTime(contentResolver, id_me, id_u)[0];
		}

		public static long[] getMaxOrderNumAndSendTime(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_MSG_SEND,
					new String[]{MSG.DbColumns.MsgSend._ORDER_NUM, MSG.DbColumns.MsgSend._TIME_LOCAL},
					MSG.DbColumns.MsgSend._ID_ME + "=? AND " + MSG.DbColumns.MsgSend._ID_U + "=?",
					new String[]{String.valueOf(id_me), String.valueOf(id_u)}, MSG.DbColumns.MsgSend._ORDER_NUM + " DESC");
			long orderNum = 0, sendTime = 0;
			if (cursor != null) {
				if( cursor.moveToFirst()) {
					orderNum = cursor.getLong(0);
					sendTime = cursor.getLong(1);
				}
				cursor.close();
			}
			return new long[]{orderNum, sendTime};
		}

		public static Cursor getCursorOrderNumDesc(ContentResolver contentResolver, long id_me, long id_u) {
			return contentResolver.query(MSG.URI_MSG_SEND, null, MSG.DbColumns.MsgSend._ID_ME + "=? AND " +
					MSG.DbColumns.MsgSend._ID_U + "=?", new String[]{String.valueOf(id_me), String.valueOf(id_u)},
					MSG.DbColumns.MsgSend._ORDER_NUM + " DESC");
		}

		public static MsgBean getSendMsgBeanWithIdUri(ContentResolver contentResolver, Uri uri, long id_me, long id_u, long targetOrderNum) {
			long id = ContentUris.parseId(uri);
			if (id < 0) throw new IllegalArgumentException("参数uri不带id部分:" + uri);
			MsgBean bean = null;
			Cursor cursor = contentResolver.query(ContentUris.withAppendedId(MSG.URI_MSG_SEND, id), null, null, null, null);
			if (cursor != null) {
				if (cursor.moveToNext()) {
					long mid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ID_ME));
					long uid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ID_U));
					long orderNum = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ORDER_NUM));
					if (mid == id_me && uid == id_u && orderNum > targetOrderNum) {
						id = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ID));
						int ctype = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgSend._TYPE_CONTENT));
						String content = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.MsgSend._CONTENT));
						int arriveState = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ARRIVE_STATE));
						bean = new MsgBean(id, MsgBean.TYPE_ME, ctype, content, orderNum, 0, arriveState);
						bean.timeSend = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._TIME_LOCAL));
					}
				}
				cursor.close();
			}
			return bean;
		}

		public static MsgBean getLastSendMsg(ContentResolver contentResolver, long id_me, long id_u) {
			MsgBean bean = null;
			Cursor cursor = getCursorOrderNumDesc(contentResolver, id_me, id_u);
			if (cursor != null) {
				if (cursor.moveToNext()) {
					long id = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ID));
					long orderNum = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ORDER_NUM));
					int ctype = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgSend._TYPE_CONTENT));
					String content = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.MsgSend._CONTENT));
					int arriveState = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgSend._ARRIVE_STATE));
					bean = new MsgBean(id, MsgBean.TYPE_ME, ctype, content, orderNum, 0, arriveState);
					bean.timeSend = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgSend._TIME_LOCAL));
				}
				cursor.close();
			}
			return bean;
		}
	}

	public static final class MSG_RECEIVED {

		public static synchronized long receive(ContentResolver contentResolver, long id_me, MsgReceived msgReceived) {
			ContentValues values = new  ContentValues();
			values.put(MSG.DbColumns.MsgReceived._ID_ME, id_me);
			values.put(MSG.DbColumns.MsgReceived._ID_U, msgReceived.fromuid);
			values.put(MSG.DbColumns.MsgReceived._TYPE_SENDER, msgReceived.sendtype);
			values.put(MSG.DbColumns.MsgReceived._TYPE_CONTENT, msgReceived.ctype);
			values.put(MSG.DbColumns.MsgReceived._CONTENT, msgReceived.cvalue);
			values.put(MSG.DbColumns.MsgReceived._TIME_SEND, msgReceived.sendtime);
			values.put(MSG.DbColumns.MsgReceived._NO, msgReceived.no);
			long id;
			synchronized (ContentHelper.class) {
				msgReceived._order_num = getMaxOrderNumSendOrReceived(contentResolver, id_me, msgReceived.fromuid) + 1;
				values.put(MSG.DbColumns.MsgReceived._ORDER_NUM, msgReceived._order_num);
				id = ContentUris.parseId(contentResolver.insert(MSG.URI_MSG_RECEIVED, values));
			}
			ARRIVE_STATE.sendBackStateReceived(contentResolver, id_me, msgReceived.fromuid, msgReceived.no);
			return id;
		}

		public static synchronized void delete(ContentResolver contentResolver, long id_me, long id_u) {
			contentResolver.delete(MSG.URI_MSG_RECEIVED, MSG.DbColumns.MsgReceived._ID_ME + "=? AND " +
					MSG.DbColumns.MsgReceived._ID_U + "=?", new String[]{String.valueOf(id_me), String.valueOf(id_u)});
		}

		public static long getMaxOrderNum(ContentResolver contentResolver, long id_me, long id_sender) {
			return getMaxOrderNumAndSendTime(contentResolver, id_me, id_sender)[0];
		}

		public static long[] getMaxOrderNumAndSendTime(ContentResolver contentResolver, long id_me, long id_sender) {
			Cursor cursor = contentResolver.query(MSG.URI_MSG_RECEIVED,
					new String[]{MSG.DbColumns.MsgReceived._ORDER_NUM, MSG.DbColumns.MsgReceived._TIME_SEND},
					MSG.DbColumns.MsgReceived._ID_ME + "=? AND " + MSG.DbColumns.MsgReceived._ID_U + "=?",
					new String[]{String.valueOf(id_me), String.valueOf(id_sender)}, MSG.DbColumns.MsgReceived._ORDER_NUM + " DESC");
			long orderNum = 0, sendTime = 0;
			if (cursor != null) {
				if( cursor.moveToFirst()) {
					orderNum = cursor.getLong(0);
					sendTime = convertServerTimeToLocal(cursor.getLong(1));
				}
				cursor.close();
			}
			return new long[]{orderNum, sendTime};
		}

		public static Cursor getCursorOrderNumDesc(ContentResolver contentResolver, long id_me, long id_u) {
			return contentResolver.query(MSG.URI_MSG_RECEIVED, null, MSG.DbColumns.MsgReceived._ID_ME + "=? AND " +
					MSG.DbColumns.MsgReceived._ID_U + "=?", new String[]{String.valueOf(id_me), String.valueOf(id_u)},
					MSG.DbColumns.MsgReceived._ORDER_NUM + " DESC");
		}

		public static List<Long> getStrangerUIDs(ContentResolver contentResolver, long id_me) {
			Cursor cursor = contentResolver.query(MSG.URI_MSG_RECEIVED, new String[]{MSG.DbColumns.MsgReceived._ID_U},
					MSG.DbColumns.MsgReceived._ID_ME + "=" + id_me + " AND " +
							MSG.DbColumns.MsgReceived._ID_U + " NOT IN(" +
							ArrayUtils.join(RELATIONSHIP.getChatFriendsUIDs(contentResolver, id_me).toArray(), ",") +
							")", null, null);
			List<Long> list = new ArrayList<Long>();
			if (cursor != null) {
				while (cursor.moveToNext()) {
					list.add(cursor.getLong(0));
				}
				cursor.close();
			}
			return list;
		}

		public static int getStrangerCount(ContentResolver contentResolver, long id_me) {
			Cursor cursor = contentResolver.query(MSG.URI_MSG_RECEIVED, new String[]{"COUNT(DISTINCT " + MSG.DbColumns.MsgReceived._ID_U + ")"},
					MSG.DbColumns.MsgReceived._ID_ME + "=" + id_me + " AND " +
							MSG.DbColumns.MsgReceived._ID_U + " NOT IN(" +
							ArrayUtils.join(RELATIONSHIP.getChatFriendsUIDs(contentResolver, id_me).toArray(), ",") +
							")", null, null);
			if (cursor != null) {
				if (cursor.moveToNext()) return cursor.getInt(0);
				cursor.close();
			}
			return 0;
		}

		public static int getCountUnread(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_MSG_RECEIVED, new String[]{"COUNT(*)"},
					MSG.DbColumns.MsgReceived._ID_ME + "=? AND " +
							MSG.DbColumns.MsgReceived._ID_U + "=? AND " + MSG.DbColumns.MsgReceived._READ_TIMES + "=0",
							new String[]{String.valueOf(id_me), String.valueOf(id_u)}, null);
			if (cursor != null) {
				if (cursor.moveToNext()) return cursor.getInt(0);
				cursor.close();
			}
			return 0;
		}

		public static long getNo(ContentResolver contentResolver, long _id) {
			Cursor cursor = contentResolver.query(ContentUris.withAppendedId(MSG.URI_MSG_RECEIVED, _id), new String[]{MSG.DbColumns.MsgReceived._NO}, null, null, null);
			long no = 0;
			if (cursor != null) {
				if (cursor.moveToNext()) {
					no = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._NO));
				}
				cursor.close();
			}
			return no;
		}

		public static void updateReadTimes(ContentResolver contentResolver, long _id, int num) {
			ContentValues values = new  ContentValues();
			values.put(MSG.DbColumns.MsgReceived._READ_TIMES, num);
			contentResolver.update(ContentUris.withAppendedId(MSG.URI_MSG_RECEIVED, _id), values, null, null);

			//TODO 删除所有已读的
		}

		public static MsgBean getReceivedMsgBeanWithIdUri(ContentResolver contentResolver, Uri uri, long id_me, long id_u, long targetOrderNum) {
			long id = ContentUris.parseId(uri);
			if (id < 0) throw new IllegalArgumentException("参数uri不带id部分:" + uri);
			MsgBean bean = null;
			Cursor cursor = contentResolver.query(ContentUris.withAppendedId(MSG.URI_MSG_RECEIVED, id), null, null, null, null);
			if (cursor != null) {
				if (cursor.moveToNext()) {
					long mid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._ID_ME));
					long uid = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._ID_U));
					long orderNum = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._ORDER_NUM));
					if (mid == id_me && uid == id_u && orderNum > targetOrderNum) {
						id = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._ID));
						int ctype = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._TYPE_CONTENT));
						String content = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._CONTENT));
						int timeLength = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._TIME_LENGTH));
						int readTimes = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._READ_TIMES));
						bean = new MsgBean(id, MsgBean.TYPE_OTHER, ctype, content, orderNum, timeLength);
						bean.timeSend = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.MsgReceived._TIME_SEND));
						bean.readTimes = readTimes;
					}
				}
				cursor.close();
			}
			return bean;
		}
	}

	public static final class ARRIVE_STATE_UNLOAD {

		public static void receive(ContentResolver contentResolver, long id_me, ArriveStateUnload asul) {
			if(asul.infos != null) {
				ContentValues values = new  ContentValues();
				for (Info info : asul.infos) {
					values.put(MSG.DbColumns.ArriveStateUnload._ID_U, info.uid);
					values.put(MSG.DbColumns.ArriveStateUnload._TIME_SEND, info.time);
					values.put(MSG.DbColumns.ArriveStateUnload._NUM, info.num);

					values.put(MSG.DbColumns.ArriveStateUnload._ID_ME, id_me);
					if (asul.isUserReceivedNum()) {
						values.put(MSG.DbColumns.ArriveStateUnload._STATE, 4);
					} else if (asul.isUserReadNum()) {
						values.put(MSG.DbColumns.ArriveStateUnload._STATE, 5);
					}
					contentResolver.insert(MSG.URI_ARRIVE_STATE_UNLOAD, values);
				}
				values.clear();
			}
		}

		public static void deleteOrUpdate(ContentResolver contentResolver, long id_me, ArriveState arriveState) {
			if (arriveState.unloadnum > 0) {
				ContentValues values = new  ContentValues();
				values.put(MSG.DbColumns.ArriveStateUnload._NUM, arriveState.unloadnum);
				contentResolver.update(MSG.URI_ARRIVE_STATE_UNLOAD, values,
						MSG.DbColumns.ArriveStateUnload._ID_ME + "=? AND " + MSG.DbColumns.ArriveStateUnload._ID_U + "=?",
						new String[]{String.valueOf(id_me), String.valueOf(arriveState.sendid)});
			} else {
				contentResolver.delete(MSG.URI_ARRIVE_STATE_UNLOAD,
						MSG.DbColumns.ArriveStateUnload._ID_ME + "=? AND " + MSG.DbColumns.ArriveStateUnload._ID_U + "=?",
						new String[]{String.valueOf(id_me), String.valueOf(arriveState.sendid)});
			}
		}
	}

	public static final class ARRIVE_STATE {

		public static void updateNotSendWithSendEntityId(ContentResolver contentResolver, long sendEntityId) {
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.MsgSend._ARRIVE_STATE, 1);
			contentResolver.update(MSG.URI_ARRIVE_STATE, values, MSG.DbColumns.MsgSend._ID_SEND_ENTITY + "=" + sendEntityId, null);
		}

		public static void updateSendedWithSendEntityId(ContentResolver contentResolver, long sendEntityId) {
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.MsgSend._ARRIVE_STATE, 2);
			contentResolver.update(MSG.URI_ARRIVE_STATE, values, MSG.DbColumns.MsgSend._ID_SEND_ENTITY + "=" + sendEntityId, null);
		}

		public static void receive(ContentResolver contentResolver, long id_me, ArriveState arriveState) {
			int state = 1;
			if (arriveState.isServerHandle()) {
				state = 3;
			} else if (arriveState.isUserReceived()) {
				state = 4;
			} else if (arriveState.isUserRead()) {
				state = 5;
			}
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.MsgSend._ARRIVE_STATE, state);
			if (arriveState.no != null && arriveState.no.length > 0) {
				contentResolver.update(MSG.URI_ARRIVE_STATE, values, MSG.DbColumns.MsgSend._ID_U + "=? AND " + MSG.DbColumns.MsgSend._NO + " IN(?)",
						new String[]{String.valueOf(arriveState.sendid), ArrayUtils.join(ArrayUtils.toObject(arriveState.no), ", ")});
			}
			if (state >= 4) {
				ARRIVE_STATE_UNLOAD.deleteOrUpdate(contentResolver, id_me, arriveState);
			}
		}

		public static void sendBackStateReceived(ContentResolver contentResolver, long id_me, long id_u, long... no) {
			SEND_ENTITY.insertNewEntity(contentResolver, id_me, id_u, 
					new StateBack(StateBack.TYPE_RECEIVED, id_u, no), true, System.currentTimeMillis(), 0);
		}

		public static void sendBackStateRead(ContentResolver contentResolver, long id_me, long id_u, long _id) {
			long no = ContentHelper.MSG_RECEIVED.getNo(contentResolver, _id);
			if (no > 0) {
				SEND_ENTITY.insertNewEntity(contentResolver, id_me, id_u, 
						new StateBack(StateBack.TYPE_READ, id_u, no), true, System.currentTimeMillis(), 0);
			}
		}

		/*public static void sendBackState(ContentResolver contentResolver, long id_me, long id_u, StateBack stateBack) {
			SEND_ENTITY.insertNewEntity(contentResolver, id_me, id_u, stateBack, System.currentTimeMillis(), 0);
		}*/
	}

	public static final class RELATIONSHIP {

		public static void insertOrUpdate(ContentResolver contentResolver, long id_me, long id_u, RelationshipBean relationship) {
			ContentValues values = new ContentValues();
			if (relationship.name != null) values.put(MSG.DbColumns.Relationship._NAME, relationship.name);
			if (relationship.faceUrl != null) values.put(MSG.DbColumns.Relationship._ICON, relationship.faceUrl);
			if (relationship.gender >= 0) values.put(MSG.DbColumns.Relationship._GENDER, relationship.gender);
			if (relationship.birthday != 0) values.put(MSG.DbColumns.Relationship._BIRTHDAY, relationship.birthday);
			if (relationship.causerie != null) values.put(MSG.DbColumns.Relationship._CAUSERIE, relationship.causerie);
			if (relationship.relation >= 0) values.put(MSG.DbColumns.Relationship._RELATION, relationship.relation);
			if (relationship.timeAdd > 0) values.put(MSG.DbColumns.Relationship._TIME_ADD, relationship.timeAdd);
			if (relationship.state >= 0) values.put(MSG.DbColumns.Relationship._STATE, relationship.state);
			if (hasRow(contentResolver, id_me, id_u)) {
				contentResolver.update(MSG.URI_RELATIONSHIP, values,
						MSG.DbColumns.Relationship._ID_ME + "=? AND " + MSG.DbColumns.Relationship._ID_U + "=?",
						new String[]{String.valueOf(id_me), String.valueOf(id_u)});
			} else {
				values.put(MSG.DbColumns.Relationship._ID_ME, relationship.mid);
				values.put(MSG.DbColumns.Relationship._ID_U, relationship.uid);
				if (relationship.relaChat >= 0) values.put(MSG.DbColumns.Relationship._RELA_CHAT, relationship.relaChat);
				contentResolver.insert(MSG.URI_RELATIONSHIP, values);
			}
		}

		public static RelationshipBean getRelationship(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_RELATIONSHIP, null,
					MSG.DbColumns.Relationship._ID_ME + "=? AND " + MSG.DbColumns.Relationship._ID_U + "=?",
					new String[]{String.valueOf(id_me), String.valueOf(id_u)}, null);
			RelationshipBean relationship = null;
			if (cursor != null) {
				if (cursor.moveToNext()) {
					relationship = new RelationshipBean(cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.Relationship._ID_ME)),
							cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.Relationship._ID_U)));
					relationship._id = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.Relationship._ID));
					relationship.name = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.Relationship._NAME));
					relationship.faceUrl = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.Relationship._ICON));
					relationship.gender = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.Relationship._GENDER));
					relationship.birthday = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.Relationship._BIRTHDAY));
					relationship.causerie = cursor.getString(cursor.getColumnIndex(MSG.DbColumns.Relationship._CAUSERIE));
					relationship.relaChat = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.Relationship._RELA_CHAT));
					relationship.relation = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.Relationship._RELATION));
					relationship.timeAdd = cursor.getLong(cursor.getColumnIndex(MSG.DbColumns.Relationship._TIME_ADD));
					relationship.state = cursor.getInt(cursor.getColumnIndex(MSG.DbColumns.Relationship._STATE));
				}
				cursor.close();
			}
			return relationship;
		}

		public static void deleteRelationship(ContentResolver contentResolver, long id_me, long id_u) {
			contentResolver.delete(MSG.URI_RELATIONSHIP, MSG.DbColumns.Relationship._ID_ME + "=? AND " + MSG.DbColumns.Relationship._ID_U + "=?",
					new String[]{String.valueOf(id_me), String.valueOf(id_u)});
		}

		public static int updateChatRelaChatToOther(ContentResolver contentResolver, long id_me, long id_u) {
			insertOrUpdateChatRelation(contentResolver, id_me, id_u, 1);
			return 1;
		}

		public static int updateChatRelaChatEachOther(ContentResolver contentResolver, long id_me, long id_u) {
			insertOrUpdateChatRelation(contentResolver, id_me, id_u, 2);
			return 2;
		}

		private static void insertOrUpdateChatRelation(ContentResolver contentResolver, long id_me, long id_u, int chatRelation) {
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.Relationship._RELA_CHAT, chatRelation);
			if (hasRow(contentResolver, id_me, id_u)) {
				contentResolver.update(MSG.URI_RELATIONSHIP, values, MSG.DbColumns.Relationship._ID_ME + "=? AND " +
						MSG.DbColumns.Relationship._ID_U + "=?", new String[]{String.valueOf(id_me), String.valueOf(id_u)});
			} else {
				values.put(MSG.DbColumns.Relationship._ID_ME, id_me);
				values.put(MSG.DbColumns.Relationship._ID_U, id_u);
				contentResolver.insert(MSG.URI_RELATIONSHIP, values);
			}
		}

		public static boolean hasRow(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_RELATIONSHIP, null, MSG.DbColumns.Relationship._ID_ME + "=? AND " +
					MSG.DbColumns.Relationship._ID_U + "=?", new String[]{String.valueOf(id_me), String.valueOf(id_u)}, null);
			return cursor.moveToNext();
		}

		/**获取聊天关系**/
		public static int getChatRelation(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_RELATIONSHIP, new String[]{MSG.DbColumns.Relationship._RELA_CHAT},
					MSG.DbColumns.Relationship._ID_ME + "=? AND " + MSG.DbColumns.Relationship._ID_U + "=?",
					new String[]{String.valueOf(id_me), String.valueOf(id_u)}, null);
			if (cursor != null) {
				if (cursor.moveToNext()) return cursor.getInt(0);
				cursor.close();
			}
			return 0;
		}

		public static int updateStateOffline(ContentResolver contentResolver, long id_me, long id_u) {
			updateState(contentResolver, id_me, id_u, 0);
			return 0;
		}

		public static int updateStateOnline(ContentResolver contentResolver, long id_me, long id_u) {
			updateState(contentResolver, id_me, id_u, 1);
			return 1;
		}

		private static void updateState(ContentResolver contentResolver, long id_me, long id_u, int state) {
			ContentValues values = new ContentValues();
			values.put(MSG.DbColumns.Relationship._STATE, state);
			contentResolver.update(MSG.URI_RELATIONSHIP, values, MSG.DbColumns.Relationship._ID_ME + "=? AND " +
					MSG.DbColumns.Relationship._ID_U + "=?", new String[]{String.valueOf(id_me), String.valueOf(id_u)});
		}

		public static boolean getStateOnline(ContentResolver contentResolver, long id_me, long id_u) {
			return getState(contentResolver, id_me, id_u) == 1;
		}

		private static int getState(ContentResolver contentResolver, long id_me, long id_u) {
			Cursor cursor = contentResolver.query(MSG.URI_RELATIONSHIP, new String[]{MSG.DbColumns.Relationship._STATE},
					MSG.DbColumns.Relationship._ID_ME + "=? AND " + MSG.DbColumns.Relationship._ID_U + "=?",
					new String[]{String.valueOf(id_me), String.valueOf(id_u)}, null);
			if (cursor != null) {
				if (cursor.moveToNext()) return cursor.getInt(0);
				cursor.close();
			}
			return 0;
		}

		/**获取聊天关系为互相发过消息的，要显示在好友列表中。注意不涉及关注关系**/
		public static List<Long> getChatFriendsUIDs(ContentResolver contentResolver, long id_me) {
			Cursor cursor = contentResolver.query(MSG.URI_RELATIONSHIP, new String[]{MSG.DbColumns.Relationship._ID_U},
					MSG.DbColumns.Relationship._ID_ME + "=" + id_me + " AND " + MSG.DbColumns.Relationship._RELA_CHAT + ">0", null, null);
			List<Long> list = new ArrayList<Long>();
			if (cursor != null) {
				while (cursor.moveToNext()) {
					list.add(cursor.getLong(0));
				}
				cursor.close();
			}
			return list;
		}
	}
}
